﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Reflection;

namespace devtm.Types
{
    public class AssemblyDescription
    {

        internal string _toString;

        public static AssemblyDescription Get(string txt, bool nullVersion, bool nullCulture, bool nullPublicKeyToken)
        {
            AssemblyDescription description = new AssemblyDescription(txt);

            if (nullVersion)
                description.Version = null;

            if (nullCulture)
                description.Culture = null;

            if (nullPublicKeyToken)
                description.PublicKeyToken = string.Empty;

            return description;
        }

        internal protected AssemblyDescription(string txt)
        {

            _toString = txt;

            string[] arr = txt.Split(',');
            foreach (string item in arr)
            {

                string[] ar = item.Split('=');
                switch (ar[0].Trim())
                {
                        
                    case "Version":
                        Version = new Version(ar[1].Trim());
                        break;

                    case "Culture":
                        Culture = ar[1].Trim() == "neutral" ? CultureInfo.InvariantCulture : CultureInfo.GetCultureInfo(ar[1].Trim());
                        break;

                    case "PublicKeyToken":
                        PublicKeyToken = ar[1].Trim();
                        break;

                    case "processorArchitecture":
                        processorArchitecture = ar[1].Trim();
                        break;
                    default:
                        AssemblyName = ar[0].Trim();
                        break;
                }


                this.Path = AssemblyName.Split('.').ToList();
                this._level1 = this.Path.First();

            }

        }

        public string AssemblyName { get; protected set; }

        public List<string> Path { get; protected set; }

        private string _level1;
        public string Level1 { get { return _level1; } }

        public Version Version { get; internal set; }

        public CultureInfo Culture { get; internal set; }

        public string PublicKeyToken { get; internal set; }

        public string processorArchitecture { get; internal set; }

        public int HashCode { get; set; }

        public override string ToString()
        {
            return _toString;
        }

        public string ToSmallString()
        {
            return AssemblyName + " (" + Version.ToString() + ")";
        }

        public override bool Equals(object obj)
        {
            if (obj is AssemblyDescription)
            {
                
                AssemblyDescription ass = obj as AssemblyDescription;
                if (Culture != null && ass.Culture != null && ass.Culture.DisplayName != this.Culture.DisplayName)
                    return false;

                if (Version != null && ass.Version != null && ass.Version.ToString() != this.Version.ToString())
                    return false;

                if (!string.IsNullOrEmpty(PublicKeyToken) && !string.IsNullOrEmpty(ass.PublicKeyToken) && ass.PublicKeyToken != this.PublicKeyToken)
                    return false;
                
                return ass.AssemblyName == AssemblyName;

            }
            return false;
        }

    }


   
}
